package com.bringspring.system.print.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.database.model.DbFieldMod;
import com.bringspring.common.database.model.dto.PreparedStatementDTO;
import com.bringspring.common.database.util.ConnUtil;
import com.bringspring.common.database.model.DataSourceModel;
import com.bringspring.common.database.util.JdbcUtil;
import com.bringspring.common.exception.DataException;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.treeutil.SumTree;
import com.bringspring.common.util.treeutil.newtreeutil.TreeDotUtils;
import com.bringspring.system.base.entity.DictionaryDataEntity;
import com.bringspring.system.base.entity.DictionaryTypeEntity;
import com.bringspring.system.base.service.DblinkService;
import com.bringspring.system.base.service.DictionaryDataService;
import com.bringspring.system.base.service.DictionaryTypeService;
import com.bringspring.system.permission.entity.UserEntity;
import com.bringspring.system.permission.service.UserService;
import com.bringspring.system.print.entity.OperatorRecordEntity;
import com.bringspring.system.print.entity.PrintDevEntity;
import com.bringspring.system.print.mapper.PrintDevMapper;
import com.bringspring.system.print.model.PaginationPrint;
import com.bringspring.system.print.model.PrintDevTreeModel;
import com.bringspring.system.print.model.vo.PrintDevVO;
import com.bringspring.system.print.service.IPrintDevService;
import com.bringspring.system.print.util.PrintDevUtil;
import lombok.Cleanup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.util.*;

/**
 * 打印模板-服务实现类
 *
 * @author 开发平台组 YY
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月30日
 */
@Service
public class PrintDevServiceImpl extends ServiceImpl<PrintDevMapper, PrintDevEntity> implements IPrintDevService {

    @Autowired
    private DictionaryDataService dictionaryDataService;
    @Autowired
    private DictionaryTypeService dictionaryTypeService;
    @Autowired
    private UserService userService;
    @Autowired
    private DataSourceModel dataSourceModel;
    @Autowired
    private DblinkService dblinkService;

    @Override
    public List<PrintDevEntity> getList(PaginationPrint paginationPrint) {
        QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(paginationPrint.getKeyword())) {
            queryWrapper.lambda().and(
                    t-> t.like(PrintDevEntity::getFullName, paginationPrint.getKeyword()).or().like(PrintDevEntity::getEnCode, paginationPrint.getKeyword())
            );
        }
        if (StringUtils.isNotEmpty(paginationPrint.getCategory())) {
            queryWrapper.lambda().eq(PrintDevEntity::getCategory, paginationPrint.getCategory());
        }
        queryWrapper.lambda().orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
        Page<PrintDevEntity> page = new Page<>(paginationPrint.getCurrentPage(), paginationPrint.getPageSize());
        IPage<PrintDevEntity> iPage = this.page(page, queryWrapper);
        return paginationPrint.setData(iPage.getRecords(), page.getTotal());
    }

    @Override
    public List<PrintDevVO> getTreeModel() throws Exception {
        QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
        return setTreeModel(this.list(queryWrapper));
    }

    @Override
    public List<PrintDevVO> getTreeModel(Integer type) throws Exception {
        QueryWrapper<PrintDevEntity> query = new QueryWrapper<>();
        query.lambda().eq(PrintDevEntity::getType, type).orderByAsc(PrintDevEntity::getSortCode).orderByDesc(PrintDevEntity::getCreatorTime);
        List<PrintDevEntity> printEntityList = this.list(query);
        return setTreeModel(printEntityList);
    }

    private List<PrintDevVO> setTreeModel(List<PrintDevEntity> printEntityList) throws Exception {
        String encode = "printDev";
        //数据字典缺失
        DictionaryTypeEntity DictionaryType = dictionaryTypeService.getInfoByEnCode(encode);
        if(DictionaryType == null){
            throw new Exception(MsgCode.PRI002.get());
        }
        List<DictionaryDataEntity> dicDataList = dictionaryDataService.
                getList(DictionaryType.getId());
        List<PrintDevTreeModel> modelAll = new LinkedList<>();
        //设置树形主节点（不显示没有子集的）
        for (DictionaryDataEntity dicEntity : dicDataList) {
            PrintDevTreeModel model = new PrintDevTreeModel();
            model.setFullName(dicEntity.getFullName());
            model.setId(dicEntity.getId());
            Long num = printEntityList.stream().filter(t -> t.getCategory().equals(dicEntity.getEnCode())).count();
            //编码底下存在的子节点总数
            if (num > 0) {
                model.setNum(Integer.parseInt(num.toString()));
                modelAll.add(model);
            }
        }
        List<String> userId = new ArrayList<>();
        printEntityList.forEach(t -> {
            userId.add(t.getCreatorUserId());
            if (StringUtils.isNotEmpty(t.getLastModifyUserId())) {
                userId.add(t.getLastModifyUserId());
            }
        });
        List<UserEntity> userList = userService.getUserName(userId);
        //设置子节点分支
        for (PrintDevEntity printEntity : printEntityList) {
            DictionaryDataEntity dicDataEntity = dicDataList.stream()
                    .filter(t -> t.getEnCode().equals(printEntity.getCategory())).findFirst().orElse(null);
            //如果字典存在则装入容器
            PrintDevTreeModel model = JsonUtil.getJsonToBean(printEntity, PrintDevTreeModel.class);
            if (dicDataEntity != null) {
                //创建者
                UserEntity creatorUser = userList.stream().filter(t -> t.getId().equals(model.getCreatorUserId())).findFirst().orElse(null);
                model.setCreatorUserId(creatorUser != null ? creatorUser.getRealName() : "");
                //修改人
                UserEntity lastmodifyuser = userList.stream().filter(t -> t.getId().equals(model.getLastModifyUserId())).findFirst().orElse(null);
                model.setLastModifyUserId(lastmodifyuser != null ? lastmodifyuser.getRealName(): "");

                model.setParentId(dicDataEntity.getId());
                modelAll.add(model);
            }
        }
        List<SumTree<PrintDevTreeModel>> trees = TreeDotUtils.convertListToTreeDot(modelAll);
        List<PrintDevVO> list = JsonUtil.getJsonToList(trees, PrintDevVO.class);
        return list;
    }

    @Override
    public Boolean checkNameExist(String fullName, String id) {
        QueryWrapper<PrintDevEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PrintDevEntity::getFullName, fullName);
        if (!StringUtils.isEmpty(id)) {
            queryWrapper.lambda().ne(PrintDevEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public List<OperatorRecordEntity> getFlowTaskOperatorRecordList(String taskId) {
        List<OperatorRecordEntity> operatorRecordList = null;
        try {
            // TODO 不同库之间的表名大小写问题
            String sql = "SELECT * FROM flow_taskoperatorrecord WHERE F_TaskId = '?' ORDER BY F_HandleTime";
            @Cleanup Connection conn = ConnUtil.getConn(dataSourceModel);
            operatorRecordList = JdbcUtil.queryCustomMods(new PreparedStatementDTO(conn, sql, taskId), OperatorRecordEntity.class);
            //已办人员
            operatorRecordList.forEach(or -> {
                or.setHandleTime(or.getHandleTimeOrigin().getTime());
                UserEntity userEntity = userService.getInfo(or.getHandleId());
                or.setUserName(userEntity != null ? userEntity.getRealName(): "");
            });
        } catch (Exception e) {
            e.getMessage();
        }
        return operatorRecordList;
    }

    @Override
    public Map<String, Object> getDataBySql(String dbLinkId, String sqlTempLate, int type) throws Exception {
        @Cleanup Connection conn = null;
        //获取连接
        if ("0".equals(dbLinkId)) {
            conn = ConnUtil.getConn(dataSourceModel);
        } else {
            conn = ConnUtil.getConn(dblinkService.getInfo(dbLinkId));
        }
        Map<String, Object> map = new TreeMap<>();
        //转换json
        List<Map<String, Object>> sqlList = JsonUtil.getJsonToList(JSONArray.parseArray(sqlTempLate));
        for (int i = 0; i < sqlList.size(); i++) {
            List<List<DbFieldMod>> dataList = null;
            try {
                String sql = sqlList.get(i).get("sql").toString();
                dataList = JdbcUtil.queryIncludeFieldMods(new PreparedStatementDTO(conn, sql));
                if (dataList.size() == 0) {
                    dataList = (JdbcUtil.queryTableFields(new PreparedStatementDTO(conn, sql)));
                }
            } catch (DataException e) {
                throw new Exception(MsgCode.PRI005.get().replace("{index}", Integer.toString(i + 1)) + e.getMessage());
            }
            if (i == 0) {
                //获取表头信息(第一条且单条信息)
                if (dataList.size() > 1) {
                    throw new Exception(MsgCode.PRI003.get());
                } else if (dataList.size() == 0) {
                    throw new Exception(MsgCode.PRI004.get());
                }
                if (type == 1) {
                    //字段信息
                    map.put("headTable", getFieldMap(conn, dataList.get(0)));
                } else {
                    //数据信息
                    map.put("headTable", getDataMap(dataList));
                }
            } else {
                //查询子表数据信息
                if (type == 1) {
                    //字段信息
                    map.put("T" + i, getFieldMap(conn, dataList.get(0)));
                } else {
                    //数据信息
                    map.put("T" + i, getDataMap(dataList));
                }
            }
        }
        return map;
    }


    private List<Map<String, Object>> getDataMap(List<List<DbFieldMod>> dbJdbcModelList) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (List<DbFieldMod> mods : dbJdbcModelList) {
            Map<String, Object> map = new HashMap<>(16);
            for (DbFieldMod mod : mods) {
                map.put(mod.getColumnLabel(), mod.getColumnValue());
            }
            mapList.add(map);
        }
        return mapList;
    }

    private List<Map<String, Object>> getFieldMap(Connection conn,
                                                  List<DbFieldMod> dbJdbcModelList) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (DbFieldMod model : dbJdbcModelList) {
            Map<String, Object> map = new HashMap<>();
            map.put("field", model.getColumnLabel());
            String fieldComment = PrintDevUtil.compareGetColumnComment(conn, model.getTableName(), model.getColumnName());
            fieldComment = fieldComment != null ? fieldComment : "";
            map.put("fieldName", model.getColumnName() + " (" + fieldComment + ")");
            mapList.add(map);
        }
        return mapList;
    }

    public static void main(String[] args) {
        Date date = new Date();

    }

}
